#include <Windows.h>
#define WIN_32_LEAN_AND_MEAN

namespace BaseContainers {
	template <class TYPE>
	class Buffer {
	public:

		TYPE * data;
		int Size;
		int MaxSize;

		Buffer() {}

		virtual ~Buffer() {}

		//Setup the data variable
		virtual void setDataPool() = 0;
		virtual void setDataPool(int const & maxSize) = 0;
		virtual void resizeDataPool(int const & size) = 0;

		//Move all objects in the list left by the value of offset
		virtual void shiftLeft(int const & offset) = 0;
		virtual boolean shiftLeft_s(int const & offset) = 0;
		//Moves all objects between the values of start and end in the list by the value of offset
		virtual void shiftLeftex(int const & start,int const & end,int const & offset) = 0;
		virtual boolean shiftLeftex_s(int const & start,int const & end,int const & offset) = 0;

		//Move all objects in the list left by the value of offset
		virtual void shiftRight(int const & offset) = 0;
		virtual boolean shiftRight_s(int const & offset) = 0;
		//Moves all objects between the values of start and end in the list by the value of offset
		virtual void shiftRightex(int const & start,int const & end,int const & offset) = 0;
		virtual boolean shiftRightex_s(int const & start,int const & end,int const & offset) = 0;

		//Buggy
		//Reverse the last process that was called for this buffer
		virtual void reverse() = 0;
		virtual boolean reverse_s() = 0;

		//Returns the current amount of objects in the list
		virtual const int getSize() const  = 0;

		//Returns a reference to the item at index
		// does not remove the the item
		// but does allow modification of the item
		virtual TYPE * get(int const & index) = 0;

		//Returns a reference to the object so the value can
		// be evaluated but the item cannot be modified or removed.
		virtual TYPE * const at(int const & index) = 0;

		//Returns whether the list is holding any data whatsoever
		virtual boolean empty() = 0;

		//Removes and cleans up all data inside the list
		virtual void clear() = 0;

		//Removes and cleans up all data inside the list
		// and resets all the lists memory allocations
		virtual void clear_s() = 0;

		//Removes and cleans up all data inside the list
		// and resets all the lists memory allocations
		// and returns all items currently in the list before cleaning them up.
		virtual TYPE * const clear_s_r() = 0;


		//Puts objects at the beginning of the list
		virtual void add(TYPE const & obj) = 0;
		virtual boolean add_s(TYPE const & obj) = 0;

		//Adds a list of items
		virtual void add_array(TYPE * objs) = 0;
		virtual boolean add_array_s(TYPE const * const objs) = 0;
		virtual TYPE * const add_array_s_r(TYPE const * const objs) = 0;

		//Puts objects at the end of the list
		virtual void push(TYPE const & obj) = 0;
		virtual boolean push_s(TYPE const & obj) = 0;

		//Pushes a list of items
		virtual void push_array(TYPE * objs) = 0;
		virtual boolean push_array_s(TYPE const * const objs) = 0;
		virtual TYPE * const push_array_s_r(TYPE const * const objs) = 0;

		//Puts objects at the specified location in the list
		virtual void insert(int const & index,TYPE const & obj) = 0;
		virtual boolean insert_s(int const & index,TYPE const & obj) = 0;

		//Inserts an array
		virtual void insert_array(int const & index,TYPE * objs,int const & size) = 0;
		virtual boolean insert_array_s(int const & index,TYPE const * const objs,int const & size) = 0;
		virtual TYPE * const insert_array_s_r(int const & index,TYPE const * const objs,int const & size) = 0;

		//Grabs the item at the front of the list and returns it, removing it from the list
		virtual TYPE & pull() = 0;
		virtual TYPE & pull_s() = 0;

		virtual TYPE * pull_array(int const & amount) = 0;
		virtual TYPE * const pull_array_c(int const & amount) = 0;
		virtual TYPE * pull_array_s(int const & amount) = 0;
		virtual TYPE * const pull_array_s_c(int const & amount) = 0;

		//Grabs the item at the end of the list and returns it
		virtual TYPE & pop() = 0;
		virtual TYPE & pop_s() = 0;

		//Pop a set amount of objects
		virtual TYPE * pop_array(int const & amount) = 0;
		virtual TYPE * const pop_array_c(int const & amount) = 0;
		virtual TYPE * pop_array_s(int const & amount) = 0;
		virtual TYPE * const pop_array_s_c(int const & amount) = 0;
	};
}